﻿using System;
using System.Collections.Generic;

using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using System.Xml;
using System.Runtime.InteropServices;

namespace System
{
    /// <summary>
    /// 序列化帮助类
    /// </summary>
    public class CSerialize
    {
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="str">序列化后的字符</param>
        /// <returns>返回反序列化的对象</returns>
        public static T DeSerializeXML<T>(string str)
        {
            XmlSerializer ms = new XmlSerializer(typeof(T), "http://api.LvShou.com/1.0/");
            XmlReader xr = XmlReader.Create(new StringReader(str));          
            return (T)(ms.Deserialize(xr));
        }

        /// <summary>
        /// 序列化对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="obj">对象</param>
        /// <returns>序列化后表示对象的的字符串</returns>
        public static string SerializeXML<T>(T obj)
        {
            XmlSerializer ms = new XmlSerializer(typeof(T), "http://api.LvShou.com/1.0/");
            StringWriter myWriter = new StringWriter();
            ms.Serialize(myWriter, obj);
            myWriter.Close();
            return myWriter.GetStringBuilder().ToString();
        }

        /// <summary>
        /// 序列化对象为二进制 
        /// </summary>
        /// <param name="o">待序列化对象</param>
        /// <returns>返回序列化后的二进制</returns>
        public static byte[] Serialize(object o)
        {
            MemoryStream memoryStream = new MemoryStream();
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(memoryStream, o);
            return memoryStream.ToArray();
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="buffer">表示对象的二进制</param>
        /// <returns>返回反序列化后的对象</returns>
        public static T DeSerialize<T>(byte[] buffer)
        {
            MemoryStream memoryStream = new MemoryStream(buffer);
            BinaryFormatter formatter = new BinaryFormatter();

            memoryStream.Position = 0;
            T result = (T)formatter.Deserialize(memoryStream);
            return result;
        }

        /// <summary>
        /// 反序列化对象
        /// </summary>
        /// <param name="buffer">表示对象的二进制</param>
        /// <returns>返回反序列化后的对象</returns>
        public static object DeSerialize(byte[] buffer)
        {
            object result = null;
            MemoryStream memoryStream = new MemoryStream(buffer);
            BinaryFormatter formatter = new BinaryFormatter();

            memoryStream.Position = 0;
            result = formatter.Deserialize(memoryStream);
            return result;
        }

        /// <summary>
        /// 序列化值类型对象
        /// </summary>
        /// <param name="structObj">待序列化对象</param>
        /// <returns>返回序列化后的二进制</returns>
        public static byte[] StructToBytes(object structObj)
        {
            int size = Marshal.SizeOf(structObj);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.StructureToPtr(structObj, buffer, false);
                byte[] bytes = new byte[size];
                Marshal.Copy(buffer, bytes, 0, size);
                return bytes;
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="bytes">表达对象的二进制</param>
        /// <param name="strcutType">对象类型</param>
        /// <returns>返回反序列化后的对象</returns>
        public static object BytesToStruct(byte[] bytes, Type strcutType)
        {
            int size = Marshal.SizeOf(strcutType);
            IntPtr buffer = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(bytes, 0, buffer, size);
                return Marshal.PtrToStructure(buffer, strcutType);
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }
        }
    }
}
